package com.pat.web.controller;

import static com.pat.common.Constants.IS_LOGON_ATTRIBUTE_NAME;
import static com.pat.common.Constants.LOGIN_HTTPREQUEST_HEADER;
import static com.pat.common.Constants.LOGIN_USER_ID;

import java.util.Date;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.render.JsonRender;
import com.pat.common.util.CryptUtil;
import com.pat.web.ApiResponse;
import com.pat.web.NoNeedLogon;
import com.pat.web.model.LoginStatus;

public class LoginInterceptor implements Interceptor {
	/**
	 *  正常登录状态
	 *  未登录状态
	 *  登录过期
	 *  登录已被踢掉
	 */
	enum LogonStatus{
		OK("0000"),
		NO_LOGON("1001"),
		EXPIRED("1011"),
		RE_LOGON("1010");
		
		
		private String errorCode;
		private LogonStatus(String errorCode) {
			this.errorCode = errorCode;
		}
		public String getErrorCode() {
			return errorCode;
		}

	}

	@Override
	public void intercept(Invocation inv) {
		try {
			// no need to login
			if (urlMatch(inv.getActionKey())) {
				inv.invoke();
				return;
			}

			LogonStatus logonStatus = checkIsLogon(inv);
			if (logonStatus == LogonStatus.OK) {
				inv.getController().setAttr(IS_LOGON_ATTRIBUTE_NAME, true);
				inv.invoke();
			} else {
				if (isNoLogonAnnotation(inv)) {
					inv.invoke();
					return;
				}
				
				ApiResponse response = new ApiResponse();
				response.setStatusCode(logonStatus.getErrorCode());
				inv.getController().render(new JsonRender(response));
			}
		} catch (Exception e) {
			e.printStackTrace();
			ApiResponse response = new ApiResponse();
			response.setStatusCode("9999");
			response.setData(e.getMessage());
			inv.getController().renderJson(response);
		} finally {

		}

	}

	protected LogonStatus checkIsLogon(Invocation inv) {
		String userToken = inv.getController().getHeader(LOGIN_HTTPREQUEST_HEADER);
		LogonStatus logonStatus = LogonStatus.OK;
		if (userToken == null || userToken.equals("")) {
			logonStatus = LogonStatus.NO_LOGON;
		} else {
			String ut = CryptUtil.decrypt(userToken);
			if (ut == null) {
				logonStatus = LogonStatus.NO_LOGON;
			} else {
				LoginStatus loginStatus = LoginStatus.dao.findFirst("select * from login_status where user_token = ?",
						userToken);
				if (loginStatus == null){
					logonStatus = LogonStatus.RE_LOGON;
				} else if(loginStatus.getUpdateTime().getTime() + 90 * 24 * 60 * 60 * 1000L < new Date().getTime()) {
					logonStatus = LogonStatus.EXPIRED;
				} else {
					logonStatus = LogonStatus.OK;
					loginStatus.setUpdateTime(new Date()).update();
					inv.getController().setAttr(LOGIN_USER_ID, Long.valueOf(ut.split("_")[0]));
				}
			}
		}
		return logonStatus;
	}

	public boolean urlMatch(String actionKey) {
		return actionKey.startsWith("/login") || actionKey.equals("/") || actionKey.startsWith("/doc");
	}

	public boolean isNoLogonAnnotation(Invocation inv) {
		Controller controller = inv.getController();
		NoNeedLogon noNeedLogonClass = controller.getClass().getDeclaredAnnotation(NoNeedLogon.class);
		NoNeedLogon noNeedLogonMethod = inv.getMethod().getDeclaredAnnotation(NoNeedLogon.class);
		if (noNeedLogonClass != null ) {
			if(noNeedLogonMethod!=null && noNeedLogonMethod.ignore()){
				return false;
			}
			return true;
		} else {
			if (noNeedLogonMethod != null&& !noNeedLogonMethod.ignore()) {
				return true;
			}
		}
		return false;
	}

}
